﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;

namespace CacheEngine
{
    /// <summary>默认的缓存管理器</summary>
    public class DefaultCacheManager : ICacheManager
    {
        private ICacheEngine _cacheEngine;
        private IKeyGenerator _keyGenerator;

        /// <summary>默认构造</summary>
        public DefaultCacheManager()
        {
            _cacheEngine = new MemoryCacheEngine();
            _keyGenerator = new HashCodeKeyGenerator();
        }

        /// <summary></summary>
        /// <param name="methodInfo"></param>
        /// <param name="params"></param>
        /// <param name="cachedItem"></param>
        /// <returns></returns>
        public bool TryGetCacheItem<T>(MethodInfo methodInfo, object[] @params, out T cachedItem)
        {
            bool foundInCache = false;
            cachedItem = default(T);
            object temp = null;

            try
            {
                string key = GetKey(methodInfo.DeclaringType, methodInfo, @params);
                temp = _cacheEngine.Get<T>(key);
                if (temp != null)
                {
                    foundInCache = true;
                    cachedItem = (T)temp;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }

            return foundInCache;
        }


        /// <summary></summary>
        /// <param name="objectType"></param>
        /// <param name="methodInfo"></param>
        /// <param name="params"></param>
        /// <param name="item"></param>
        public virtual void SaveOrUpdate(Type objectType, MethodInfo methodInfo, object[] @params, object item)
        {
            string key = GetKey(objectType, methodInfo, @params);

            _cacheEngine.SaveOrUpdate(key, item, Attribute.ExpirationTime.GetExpirationDate());
        }

        /// <summary>缓存实现引擎</summary>
        public ICacheEngine CacheEngine { get { return _cacheEngine; } set { _cacheEngine = value; } }

        /// <summary>关键字生成器实现</summary>
        public IKeyGenerator KeyGenerator { get { return _keyGenerator; } set { _keyGenerator = value; } }

        /// <summary>自定认属性</summary>
        public CacheEngineAttribute Attribute { get; set; }

        /// <summary>取得关键字</summary>
        /// <param name="objectType"></param>
        /// <param name="methodInfo"></param>
        /// <param name="params"></param>
        /// <returns></returns>
        protected string GetKey(Type objectType, MethodInfo methodInfo, object[] @params)
        {
            return _keyGenerator.GenerateKey(objectType, methodInfo, @params);
        }
    }
}
